package com.example.demo.ctrl;

/**
 * elasticsearch_demo
 * 2019/12/5 16:20
 *
 * @author
 * @description
 **/

import com.example.demo.domain.DocBean;
import com.example.demo.service.ElasticService;
import org.apache.lucene.search.Query;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import static org.elasticsearch.index.query.QueryBuilders.matchQuery;

@RestController
@RequestMapping("/elastic")
public class ElasticController {

    @Autowired
    private ElasticService elasticService;

    @GetMapping("/init")
    public void init() {
        elasticService.createIndex();
        List<DocBean> list = new ArrayList<>();
        list.add(new DocBean(1L, "XX0193", "XX8064", "中国", 1));
        list.add(new DocBean(2L, "XX0210", "XX7475", "我是一个中国人", 1));
        list.add(new DocBean(3L, "XX0257", "XX8097", "我爱中华人民共和国", 1));
        elasticService.saveAll(list);

    }

    @GetMapping("/all")
    public Iterator<DocBean> all() {
        return elasticService.findAll();
    }

    @GetMapping("/findByContent")
    public Page<DocBean> findByContent(String content) {
        Page<DocBean> x = elasticService.findByContent(content);
        return x;
    }


    @GetMapping("/findByFirstCode")
    public Page<DocBean> findByFirstCode() {
        return elasticService.findByFirstCode("XX0193");
    }

    @GetMapping("/findBySecondCode")
    public Page<DocBean> findBySecondCode() {
        return elasticService.findBySecondCode("XX7475");
    }

    @Autowired
    private ElasticsearchRestTemplate elasticsearchTemplate;


    /**
     * 从es检索数据
     * @param content  搜索关键字
     * @param pageNum  页
     * @param pageSzie 条
     * @return
     */
    @GetMapping("/test")
    public Page<DocBean> getDocBeanListBySrt() {
//        Pageable pageable = PageRequest.of(pageNum, pageSzie);
        String content = "中国";
        Pageable pageable = PageRequest.of(0, 5);
        String preTag = "<font color='#dd4b39'>";//google的色值
        String postTag = "</font>";
        QueryBuilder matchQuery = new QueryBuilder() {
            @Override
            public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params) throws IOException {
                return null;
            }

            @Override
            public void writeTo(StreamOutput streamOutput) throws IOException {

            }

            @Override
            public String getWriteableName() {
                return null;
            }

            @Override
            public Query toQuery(QueryShardContext queryShardContext) throws IOException {
                return null;
            }

            @Override
            public Query toFilter(QueryShardContext queryShardContext) throws IOException {
                return null;
            }

            @Override
            public QueryBuilder queryName(String s) {
                return null;
            }

            @Override
            public String queryName() {
                return null;
            }

            @Override
            public float boost() {
                return 0;
            }

            @Override
            public QueryBuilder boost(float v) {
                return null;
            }

            @Override
            public String getName() {
                return null;
            }
        };

        SearchQuery searchQuery = new NativeSearchQueryBuilder().
//                withQuery(matchQuery("DocBeanTitle", content)).
        withQuery(matchQuery("DocBeanContent", content)).
//                withHighlightFields(new HighlightBuilder.Field("DocBeanTitle").preTags(preTag).postTags(postTag),
        withHighlightFields(
        new HighlightBuilder.Field("DocBeanContent").preTags(preTag).postTags(postTag)).build();
        searchQuery.setPageable(pageable);

        // 不需要高亮直接return DocBeans
        // AggregatedPage<DocBean> DocBeans = elasticsearchTemplate.queryForPage(searchQuery, DocBean.class);

        // 高亮字段
        AggregatedPage<DocBean> DocBeans = elasticsearchTemplate.queryForPage(searchQuery, DocBean.class, new SearchResultMapper() {

            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
                List<DocBean> chunk = new ArrayList<>();
                for (SearchHit searchHit : response.getHits()) {
                    if (response.getHits().getHits().length <= 0) {
                        return null;
                    }
                    DocBean DocBean = new DocBean();
                    //name or memoe
//                    HighlightField DocBeanTitle = searchHit.getHighlightFields().get("DocBeanTitle");
//                    if (DocBeanTitle != null) {
//                        DocBean.setDocBeanTitle(DocBeanTitle.fragments()[0].toString());
//                    }
                    HighlightField DocBeanContent = searchHit.getHighlightFields().get("DocBeanContent");
                    if (DocBeanContent != null) {
                        DocBean.setContent(DocBeanContent.fragments()[0].toString());
                    }

                    chunk.add(DocBean);
                }
                if (chunk.size() > 0) {
                    return new AggregatedPageImpl<>((List<T>) chunk);
                }
                return null;
            }

            @Override
            public <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {
                return null;
            }
        });
        return DocBeans;
    }
}


